<?php

namespace App\Http\Controllers\Payment;

use App\Http\Controllers\Controller;
use App\Models\Common\ApiResponse;
use App\Models\Payment\PaymentChannel;
use App\Models\Payment\PaymentScene;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class SceneController extends Controller
{
    public $name = '支付场景';

    public function index()
    {
        $user = admin();
        $dataPacket = [];
        $parkingLotID = getParkingLotID();

        $channels = PaymentChannel::where('parking_lot_id', $parkingLotID)->get();
        $defaultScenes = PaymentScene::DEFAULT;
        $paymentScenes = PaymentScene::where('parking_lot_id', $parkingLotID)->get()->groupBy('name')->map(function ($scenes) {
            return $scenes->groupBy('source');
        })->toArray() ?: [];

        foreach ($defaultScenes as $sceneName => $paymentCategoryPacket) {

            $rowDat = ['name' => $sceneName];

            foreach ($paymentCategoryPacket as $sourceName => $paymentCategories) {

                $rowDat[$sourceName] = ['options' => [], 'selected' => []];

                $sceneChannels = collect(\Arr::get($paymentScenes, $sceneName . '.' . $sourceName));

                $channels->each(function ($channel) use (&$rowDat, $paymentCategories, $sceneChannels, $sourceName) {

                    if (in_array($channel->category, $paymentCategories, true)) {
                        $rowDat[$sourceName]['options'][$channel->id] = [
                            'id' => $channel->id,
                            'name' => $channel->name
                        ];
                    }

                    if ($sceneChannels->count()) {
                        $sceneChannels = $sceneChannels->sortByDesc('sequence');
                        foreach ($sceneChannels as $sceneChannel) {
                            if ($channelID = $sceneChannel['channel_id'] ?? '') {
                                $rowDat[$sourceName]['selected'][$channelID] = $channelID;
                            }
                        }
                    }
                });
                $rowDat[$sourceName]['selected'] = array_values($rowDat[$sourceName]['selected']);
                $rowDat[$sourceName]['options'] = array_values($rowDat[$sourceName]['options']);
            }
            $dataPacket[] = $rowDat;
        }

        return ApiResponse::return('', $dataPacket);
    }

    public function all()
    {
        return ApiResponse::return('', PaymentScene::SCENES);
    }

    public function store(Request $request)
    {
        $this->admin = $user = admin();
        $paymentScenesDat = [];
        $this->parkingLotID = $parkingLotID = getParkingLotID();
        $this->logContent = '配置支付场景下的支付通道';

        if (!$sceneName = $request->get('name')) {
            return ApiResponse::fail('支付场景名称必填');
        }

        if (!in_array($sceneName, PaymentScene::SCENES, true)) {
            return ApiResponse::fail('不是合法的支付场景');
        }

        if (!$sceneSource = $request->get('source')) {
            return ApiResponse::fail('支付场景客户端必填');
        }

        if (!in_array($sceneSource, PaymentScene::SOURCES, true)) {
            return ApiResponse::fail('不是合法的支付场景客户端');
        }

        if (!$paymentCategories = \Arr::get(PaymentScene::DEFAULT, $sceneName . '.' . $sceneSource)) {
            return ApiResponse::fail('未找到支付场景对应的支付通道类别');
        }

        $channelIDs = array_unique(array_filter(explode(',', $request->get('channel_ids'))));

        if ($channelIDs) {
            $paymentChannels = PaymentChannel::query()->where('parking_lot_id', $parkingLotID)->findMany($channelIDs);
            if (!$paymentChannels->count()) {
                return ApiResponse::fail('未匹配到对应的支付通道');
            }

            foreach ($paymentChannels as $sequence => $paymentChannel) {

                if (!in_array($paymentChannel->category, $paymentCategories, true)) {
                    return ApiResponse::fail($paymentChannel->name . '在' . $sceneName . "场景下{$sceneSource}端不可用");
                }

                $paymentScenesDat[] = [
                    'id' => Str::orderedUuid()->toString(),
                    'parking_lot_id' => $parkingLotID,
                    'name' => $sceneName,
                    'source' => $sceneSource,
                    'channel_id' => $paymentChannel->id,
                    'sequence' => $sequence,
                    'created_at' => now()->toDateTimeString(),
                    'updated_at' => now()->toDateTimeString()
                ];
            }
        }

        $dbResult = \DB::transaction(function () use ($paymentScenesDat, $parkingLotID, $sceneName, $sceneSource) {
            PaymentScene::where('parking_lot_id', $parkingLotID)->where('name', $sceneName)->where('source', $sceneSource)->delete();
            if ($paymentScenesDat) {
                PaymentScene::query()->insertOrIgnore($paymentScenesDat);
            }
            return true;
        });

        if ($dbResult) {
            return ApiResponse::return();
        }

        return ApiResponse::return('', null, ApiResponse::RESP_CODE_FAILURE);
    }
}
